﻿using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.HangfireServices
{
    /// <summary>
    /// 比赛定时任务
    /// </summary>
    [ReccuringJobCron("0 0/5 * * * ?")]
    public class GameHangfireService : IHangfireService
    {
        private readonly IGameOrderRepository _gameOrderRepository;
        private readonly IGameTeamRepository _gameTeamRepository;
        private readonly IGameRepository _gameRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        /// <summary>
        /// ctor
        /// </summary>
        public GameHangfireService(
            IGameOrderRepository gameOrderRepository,
            IGameTeamRepository gameTeamRepository,
            IGameRepository gameRepository,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _gameOrderRepository = gameOrderRepository;
            _gameTeamRepository = gameTeamRepository;
            _gameRepository = gameRepository;
            _unitOfWorkManager = unitOfWorkManager;
        }

        /// <summary>
        /// 执行
        /// </summary>
        public async Task ExecuteAsync()
        {
            ////更新比赛状态为已结束
            //await (await _gameRepository.UpdatePartialAsync())
            //    .Set(m => m.State, GameStateEnum.Finished)
            //    .Where(m => m.StartDate < DateTimeOffset.Now.Date)
            //    .ExecuteAsync();
            //取消未支付活动订单
            var orderList = await _gameOrderRepository.AsNoTracking()
                .Where(m => m.BusinessType == BusinessTypeEnum.Game && m.State == GameOrderStateEnum.NotPay && m.CreateTime < DateTime.Now.AddMinutes(-5))
                .OrderBy(m => m.CreateTime).Take(100).ToListAsync();
            if (orderList.Any())
            {
                foreach (var order in orderList.GroupBy(m => m.BusinessId))
                {
                    var orderIdList = order.Select(m => m.ID).ToList();
                    using (var uow = _unitOfWorkManager.Begin())
                    {
                        await (await _gameTeamRepository.UpdatePartialAsync())
                            .Set(m => m.PayState, PayOrderStateEnum.Canceled)
                            .Set(m => m.JoinState, GameJoinStateEnum.AutoCancel)
                            .Where(m => orderIdList.Contains(m.GameOrderId))
                            .ExecuteAsync();
                        await (await _gameOrderRepository.UpdatePartialAsync())
                            .Set(m => m.State, GameOrderStateEnum.Cancel)
                            .Set(m => m.CancelTime, DateTimeOffset.Now)
                            .Set(m => m.CancelCount, m => m.JoinCount)
                            .Where(m => orderIdList.Contains(m.ID))
                            .ExecuteAsync();

                        await uow.CompleteAsync();
                    }
                }
            }
        }
    }
}
